<!--
 * @author luguoxiang
 * @date 2022/9/17
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
-->
<template>
  <div class="app-page-split">
    <div style="width: 300px" class="gl-card gl-pd0">
      <div class="gl-card-title gl-flex">
        <div class="gl-flex-1">
          <t-tooltip content="配置了的资源会进行数据权限过滤，否则不处理">资源列表</t-tooltip>
        </div>
        <t-link v-if="has('resource/create')" @click="resourceEditRef.open()">添加</t-link>
      </div>
      <div class="gl-card-body gl-pd0">
        <t-list split>
          <t-list-item
            v-for="x in resources"
            :key="x.id"
            :class="{ active: resource.id === x.id }"
            @click="changeResource(x)"
          >
            {{ x.name }}
            <template v-if="x.id !== '0'" #action>
              <t-link
                v-if="has('resource/update')"
                theme="primary"
                hover="color"
                style="margin-left: 16px"
                @click="resourceEditRef.open(x)"
                >编辑</t-link
              >
              <t-link
                v-if="has('resource/remove')"
                theme="danger"
                hover="color"
                style="margin-left: 16px"
                @click="removeResource(x)"
                >删除</t-link
              >
            </template>
          </t-list-item>
        </t-list>
      </div>
    </div>
    <div style="width: 300px" class="gl-card gl-pd0">
      <div class="gl-card-title gl-flex">
        <div class="gl-flex-1">资源规则</div>
        <t-link v-if="has('rule/create')" @click="ruleEditRef.open({ resourceId: resource.id })">添加</t-link>
      </div>
      <div class="gl-card-body gl-pd0">
        <t-list v-if="rules.length" split>
          <t-list-item v-for="x in rules" :key="x.id" :class="{ active: rule.id === x.id }" @click="changeRule(x)">
            <div>
              <t-tag v-if="x.defaulted" theme="primary" size="small">缺省</t-tag>
              {{ x.name }}
            </div>
            <template #action>
              <t-link
                v-if="has('rule/update')"
                theme="primary"
                hover="color"
                style="margin-left: 16px"
                @click="ruleEditRef.open(x)"
                >编辑</t-link
              >
              <t-link
                v-if="has('rule/remove')"
                theme="danger"
                hover="color"
                style="margin-left: 16px"
                @click="removeRule(x)"
                >删除</t-link
              >
            </template>
          </t-list-item>
        </t-list>
        <div v-else class="gl-empty">暂无数据</div>
      </div>
    </div>
    <div class="gl-flex-1 gl-pd0 gl-flex-col">
      <t-tabs v-model="tabs" class="gl-tabs-auto-h" style="flex: 1; overflow: hidden; padding: 0">
        <t-tab-panel value="1" label="规则条件">
          <div class="gl-page-box gl-card gl-h100">
            <lg-table :schema="schema" v-bind="tableProps">
              <!-- 工具栏 -->
              <template #toolbar-left>
                <lg-button-list :limit="$ToolBtnLimit">
                  <btn-tool-add
                    v-if="has('rule-item/create')"
                    @click="editRef.open({ ruleId: rule.id, provideType: 0, spliceType: 0 })"
                  />
                  <template #trigger><btn-tool-more /></template>
                </lg-button-list>
              </template>
              <!-- 操作栏 -->
              <template #actionbar="{ row }">
                <lg-button-list :limit="$RowBtnLimit">
                  <btn-row-update v-if="has('rule-item/update')" @click="editRef.open({ id: row.id })" />
                  <btn-row-remove v-if="has('rule-item/remove')" @click="remove(row.id)" />
                </lg-button-list>
              </template>
              <!-- 插槽 -->
              <template #columnValue="{ row }">
                {{ row.value }}
              </template>
            </lg-table>
            <div style="height: 12px"></div>
            <div class="gl-page-box gl-card">
              <div class="gl-card-title">SQL预览</div>
              <div class="gl-card-body gl-color-placeholder">{{ sql }}</div>
            </div>
          </div>
        </t-tab-panel>
        <t-tab-panel value="2" label="值供应器">
          <lg-table :schema="provideSchema" v-bind="provideTableProps">
            <!-- 工具栏 -->
            <template #toolbar-left>
              <lg-button-list :limit="$ToolBtnLimit">
                <btn-tool-add v-if="has('provide/create')" @click="provideEditRef.open({})" />
                <template #trigger><btn-tool-more /></template>
              </lg-button-list>
            </template>
            <!-- 操作栏 -->
            <template #actionbar="{ row }">
              <lg-button-list :limit="$RowBtnLimit">
                <btn-row-update v-if="has('provide/update')" @click="provideEditRef.open({ id: row.id })" />
                <btn-row-remove v-if="has('provide/remove')" @click="removeProvide(row.id)" />
              </lg-button-list>
            </template>
            <!-- 插槽 -->
          </lg-table>
        </t-tab-panel>
      </t-tabs>
    </div>
  </div>
  <edit ref="editRef" @ok="reload()" />
  <resource-edit ref="resourceEditRef" @ok="getResource" />
  <rule-edit ref="ruleEditRef" @ok="getRule" />
  <provide-edit ref="provideEditRef" @ok="reloadProvide()" />
  <detail ref="detailRef" />
</template>

<script setup lang="ts">
import { onMounted, ref } from 'vue';
import { formatStr, LgButtonList, LgTable, toMap, useAuth, useTable } from '@/soar';
import resourceApi from './resourceApi';
import schema, { provideSchema } from './schema';
import api from './ruleItemApi';
import Edit from './Edit.vue';
import ResourceEdit from './ResourceEdit.vue';
import RuleEdit from './RuleEdit.vue';
import ProvideEdit from './ProvideEdit.vue';
import Detail from './Detail.vue';
import ruleApi from './ruleApi';
import ruleProvideApi from './ruleProvideApi';
import { enums } from '@/api/common';

const { has } = useAuth();
const editRef = ref();
const resourceEditRef = ref();
const ruleEditRef = ref();
const provideEditRef = ref();
const detailRef = ref();

const resources = ref([]);
const rules = ref([]);
const resource = ref({});
const rule = ref({});
const provides = ref({});
const tabs = ref('1');

const SystemValueEnum = ref([]);
enums('SystemValueEnum').then((res) => {
  SystemValueEnum.value = toMap(res.SystemValueEnum, 'value', 'label');
});

function getResource() {
  resourceApi.query().then((res) => {
    res.list.unshift({ id: '0', name: '默认（适用于所有资源的规则）' });
    resources.value = res.list;
    changeResource(res.list[0]);
  });
}

ruleProvideApi.query().then((res) => {
  const map = {};
  for (const x of res.list) {
    map[x.id] = `${x.className}.${x.methodName}(${x.params || ''})`;
  }
  provides.value = map;
});

function changeResource(e: any) {
  if (e === resource.value) {
    return;
  }
  resource.value = e;
  getRule();
}

function getRule() {
  ruleApi.query({ $soarQuery: { 'resourceId-eq': resource.value.id } }).then((res) => {
    rules.value = res.list;
    changeRule(res.list[0] || { id: '0' });
  });
}

function changeRule(e: any) {
  if (e === rule.value) {
    return;
  }
  rule.value = e;
  reload(1);
}

function getValue(x) {
  if (x.provideType === 0) {
    return provides.value[x.columnValue];
  }
  if (x.provideType === 1) {
    return SystemValueEnum.value[x.columnValue];
  }
  return x.columnValue;
}

const ExpressionEnum = {
  0: ' = ${0}',
  1: ' != ${0}',
  2: ' < ${0}',
  3: ' > ${0}',
  4: ' <= ${0}',
  5: ' >= ${0}',
  6: ' LIKE "%${0}%"',
  7: ' LIKE "%${0}"',
  8: ' LIKE "${0}%"',
  9: ' NOT LIKE "%${0}%"',
  10: ' IN( ${0} )',
  11: ' NOT IN( ${0} )',
  12: ' IS NULL',
  13: ' IS NOT NULL',
};
const sql = ref('');
const { remove, reload, tableProps, handleSingle } = useTable<any>({
  api,
  props: {
    paramsHandle(params: any) {
      params.$soarQuery['ruleId-eq'] = rule.value?.id;
    },
    dataHandle(data) {
      let str = '';
      const ls = data.list;
      for (let i = 0; i < ls.length; i++) {
        const x = ls[i];
        x.value = getValue(x);
        if (i !== 0) {
          str += x.spliceType === 1 ? ' OR ' : ' AND ';
        }
        str += x.columnName + formatStr(ExpressionEnum[x.expression], [x.value]);
      }
      sql.value = str;
      return data;
    },
    fields: ['id', 'provideType'],
    orderBys: ['id'],
    actionbar: {
      width: 100,
    },
    pagination: false,
    immediate: false,
  },
});

const {
  remove: removeProvide,
  reload: reloadProvide,
  tableProps: provideTableProps,
} = useTable({
  api: ruleProvideApi,
  props: {
    actionbar: {
      width: 100,
    },
  },
});

function removeResource(e: { name: any; id: string | number }) {
  handleSingle(`确认删除“${e.name}”吗？`, () => {
    resourceApi.remove([e.id]).then(() => getResource());
  });
}

function removeRule(e: { name: any; id: string | number }) {
  handleSingle(`确认删除“${e.name}”吗？`, () => {
    ruleApi.remove([e.id]).then(() => getRule());
  });
}

onMounted(() => {
  getResource();
});
</script>
<style lang="less" scoped>
.active {
  background-color: var(--td-brand-color-1);
  color: var(--app-color-primary);
}
:deep(.t-list-item) {
  cursor: pointer;
  .t-list-item__action {
    display: none;
  }
  &:hover {
    .t-list-item__action {
      display: unset;
    }
  }
}
</style>
